package config

import (
	"os"
	"strconv"
	"strings"
	"sync"

	"github.com/joho/godotenv"
	"github.com/sirupsen/logrus"
)

var (
	config *AppConfig
	once   sync.Once
)

// AppConfig 应用配置结构体
type AppConfig struct {
	// 数据库配置
	DBHost     string `json:"db_host"`
	DBPort     int    `json:"db_port"`
	DBUser     string `json:"db_user"`
	DBPassword string `json:"db_password"`
	DBName     string `json:"db_name"`
	DBSSLMode  string `json:"db_ssl_mode"`

	// JWT配置
	JWTSecret     string `json:"jwt_secret"`
	JWTTTLMinutes int    `json:"jwt_ttl_minutes"` // JWT有效时间（分钟）

	// 服务器配置
	ServerPort int    `json:"server_port"` // Web服务器端口
	ServerHost string `json:"server_host"` // Web服务器主机名
	DebugMode  bool   `json:"debug_mode"`  // 调试模式

	// WebSocket配置
	WSPingInterval int `json:"ws_ping_interval"` // WebSocket心跳间隔(秒)
	WSPingTimeout  int `json:"ws_ping_timeout"`  // WebSocket心跳超时(秒)

	// 文件存储
	UploadPath  string `json:"upload_path"`   // 文件上传路径
	MaxUploadMB int    `json:"max_upload_mb"` // 最大上传文件大小(MB)

	// 其他配置
	LogLevel string `json:"log_level"` // 日志级别
}

// GetJWTSecret 获取JWT密钥
func GetJWTSecret() string {
	return Get().JWTSecret
}

// Get 获取配置实例
func Get() *AppConfig {
	once.Do(func() {
		initConfig()
	})
	return config
}

// initConfig 初始化配置
func initConfig() {
	// 默认值配置
	config = &AppConfig{
		DBHost:         "localhost",
		DBPort:         5432,
		DBUser:         "postgres",
		DBPassword:     "postgres",
		DBName:         "chat_app",
		DBSSLMode:      "disable",
		JWTSecret:      "your-secret-key-chat-app",
		JWTTTLMinutes:  72 * 60, // 72小时
		ServerPort:     8080,
		ServerHost:     "0.0.0.0",
		DebugMode:      false,
		WSPingInterval: 30,
		WSPingTimeout:  60,
		UploadPath:     "./uploads",
		MaxUploadMB:    10,
		LogLevel:       "info",
	}

	// 尝试加载 .env 文件
	if err := godotenv.Load(); err != nil {
		logrus.Debug("No .env file found")
	}

	// 从环境变量覆盖配置
	if host := os.Getenv("DB_HOST"); host != "" {
		config.DBHost = host
	}
	if portStr := os.Getenv("DB_PORT"); portStr != "" {
		if port, err := strconv.Atoi(portStr); err == nil {
			config.DBPort = port
		}
	}
	if user := os.Getenv("DB_USER"); user != "" {
		config.DBUser = user
	}
	if pass := os.Getenv("DB_PASSWORD"); pass != "" {
		config.DBPassword = pass
	}
	if name := os.Getenv("DB_NAME"); name != "" {
		config.DBName = name
	}
	if ssl := os.Getenv("DB_SSLMODE"); ssl != "" {
		config.DBSSLMode = ssl
	}
	if secret := os.Getenv("JWT_SECRET"); secret != "" {
		config.JWTSecret = secret
	}
	if ttlStr := os.Getenv("JWT_TTL_MINUTES"); ttlStr != "" {
		if ttl, err := strconv.Atoi(ttlStr); err == nil {
			config.JWTTTLMinutes = ttl
		}
	}
	if portStr := os.Getenv("SERVER_PORT"); portStr != "" {
		if port, err := strconv.Atoi(portStr); err == nil {
			config.ServerPort = port
		}
	}
	if host := os.Getenv("SERVER_HOST"); host != "" {
		config.ServerHost = host
	}
	if debug := os.Getenv("DEBUG_MODE"); debug != "" {
		config.DebugMode = strings.ToLower(debug) == "true"
	}
	if intervalStr := os.Getenv("WS_PING_INTERVAL"); intervalStr != "" {
		if interval, err := strconv.Atoi(intervalStr); err == nil {
			config.WSPingInterval = interval
		}
	}
	if timeoutStr := os.Getenv("WS_PING_TIMEOUT"); timeoutStr != "" {
		if timeout, err := strconv.Atoi(timeoutStr); err == nil {
			config.WSPingTimeout = timeout
		}
	}
	if path := os.Getenv("UPLOAD_PATH"); path != "" {
		config.UploadPath = path
	}
	if maxStr := os.Getenv("MAX_UPLOAD_MB"); maxStr != "" {
		if max, err := strconv.Atoi(maxStr); err == nil {
			config.MaxUploadMB = max
		}
	}
	if level := os.Getenv("LOG_LEVEL"); level != "" {
		config.LogLevel = strings.ToLower(level)
	}
}
